#ifndef _9B6F3FDA_FE4D_4E5E_B3DA_FAAFE5A09663
#define _9B6F3FDA_FE4D_4E5E_B3DA_FAAFE5A09663

/**
* @brief        增强版单例模板，三个特点：
*					1.代码精炼，仅需一个.h文件；
*					2.支持对单例对象进行初始化和反初始化；
*					3.支持在初始化时向单例对象传参；
* @param[in]    T 欲设为单例的类
* @param[in]    Args 构造函数参数类型
* @author       xktesla
*/
template <typename T, typename...Args> class ISingleton
{
public:
	/**
	* @brief        初始化单例
	* @param[in]    Args 对应模板变参
	* @return		是否初始化成功，由派生类initInst()返回值决定
	* @author       xktesla
	*/
	static bool InitInst(Args...args)
	{
		T*& pInstance = _get_static_ptr_();
		if (pInstance == nullptr)
		{
			pInstance = new T(args...);
			return pInstance->initInst();
		}
		return true;
	}

	/**
	* @brief        反初始化单例
	* @return
	* @author       xktesla
	*/
	static void UnInitInst()
	{
		T*& pInstance = _get_static_ptr_();
		if (pInstance != nullptr)
		{
			pInstance->unInitInst();
			delete pInstance;
			pInstance = nullptr;
		}
	}

	/**
	* @brief        获取单例
	* @return		单例指针
	* @author       xktesla
	*/
	static T* GetInst()
	{
		return _get_static_ptr_();
	}

protected:
	ISingleton() { }
	virtual ~ISingleton() { }

	/**
	* @brief        初始化接口，为派生类提供一次初始化机会
	* @return		是否初始化成功，将作为InitInst的返回值
	* @author       xktesla
	*/
	virtual bool initInst() { return true; };

	/**
	* @brief        反初始化接口，为派生类提供一次反初始化机会
	* @author       xktesla
	*/
	virtual void unInitInst() {};

private:
	/**
	* @brief        存储单例对象，如此设计主要用于避免多出一个cpp文件
	* @return		返回单例对象指针的引用
	* @author       xktesla
	*/
	static T*& _get_static_ptr_()
	{
		static T* pInstance = nullptr;
		return pInstance;
	};
};

#endif
